var __extends = (this && this.__extends) || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
define(["require", "exports", "../class/SVGGraphics", "../class/Tween", "./Food", "./common"], function (require, exports, SVGGraphics_1, Tween_1, Food_1, common_1) {
    "use strict";
    var skinMap = {
        "rainbow": {
            body_colors: [0x00a8df, 0x00a8df, 0x127cc3, 0x1d63b4, 0x274da5, 0x2d3f9d, 0x343395,
                0x492f93, 0x642a91, 0x702790, 0x88228e, 0x94208c, 0xa31d8b, 0xb81989, 0xcb1782,
                0xd01a76, 0xd41d6b, 0xd51e6a, 0xe0264a, 0xe72b38, 0xeb312d,
                0xf1732d, 0xf4942d, 0xf8b52d, 0xf9c02d, 0xfacf2d, 0xfbde2d, 0xf8e72d,
                0xdade32, 0xc1d736, 0x99cb3c, 0x6dbe43, 0x54b747, 0x31ac4c, 0x0ea251,
                0x0ea251, 0x00a293, 0x00a5c1],
            head_url: "/images/snake_head.png",
            head_effective_width: 160
        },
        "test_v2": {
            body_colors: (function () {
                var colors = [
                    0xcb3f3f,
                    0xcd4544,
                    0xcf4c4b,
                    0xd45655,
                    0xda6868,
                    0xdd7170,
                    0xdf7676,
                ];
                return colors.concat(colors.slice().reverse());
            })(),
            head_url: "./images/skin/test_v2/head.png",
            head_effective_width: 380,
            head_anchor: { x: 0.5, y: 0.625 }
        }
    };
    var skinNames = Object.keys(skinMap);
    var MaxKnotTexWidth = 200;
    /**单位时间内的偏移量*/
    var base_speed = 5;
    /**两点之间基础间隔 */
    // const base_spacing = 5;
    /**单位时间内的旋转量*/
    var base_deg = 36;
    // 将要回收的点，可进行重复利用
    var CG_points = [];
    function popCGPoint() {
        return CG_points.pop() || new PIXI.Point();
    }
    ;
    function pointDis(point_1, point_2) {
        return Math.sqrt(Math.pow(point_2.x - point_1.x, 2) + Math.pow(point_2.y - point_1.y, 2));
    }
    ;
    /**获取对应的边缘点 */
    function getSizePoints(pre_point, cur_point, nex_point, distance) {
        var base_direction_x = nex_point.x - pre_point.x;
        var base_direction_y = nex_point.y - pre_point.y;
        var rate_x_y = base_direction_x / base_direction_y;
        var rate_y_x = base_direction_y / base_direction_x;
        var res_direction_x = Math.sqrt(Math.pow(distance, 2) / (1 + Math.pow(rate_y_x, 2)));
        var res_direction_y = Math.sqrt(Math.pow(distance, 2) / (1 + Math.pow(rate_x_y, 2)));
        base_direction_x < 0 && (res_direction_x = -res_direction_x);
        base_direction_y < 0 && (res_direction_y = -res_direction_y);
        var left_size_point = popCGPoint();
        left_size_point.set(cur_point.x - res_direction_y, cur_point.y + res_direction_x);
        var right_size_point = popCGPoint();
        right_size_point.set(cur_point.x + res_direction_y, cur_point.y - res_direction_x);
        return [
            left_size_point,
            right_size_point,
        ];
    }
    var getLineLength = function (points) {
        var pre_point;
        var total_body_length = 0;
        for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
            var cur_point = points_1[_i];
            if (!cur_point) {
                break;
            }
            if (!pre_point) {
                pre_point = cur_point;
                continue;
            }
            total_body_length += Math.sqrt(Math.pow(cur_point.x - pre_point.x, 2) + Math.pow(cur_point.y - pre_point.y, 2));
            pre_point = cur_point;
        }
        return total_body_length;
    };
    var Snake = (function (_super) {
        __extends(Snake, _super);
        function Snake(snake_shape) {
            var _this = this;
            _super.call(this);
            this._base_spacing = 5;
            this._path = (function () {
                var pathNode = document.createElementNS("http://www.w3.org/2000/svg", "path");
                pathNode.setAttribute("stroke", "#0F0");
                pathNode.setAttribute("stroke-width", "5");
                return pathNode;
            })();
            this._body = {
                points: [],
                // con: new PIXI.ParticleContainer(0, {
                //     scale: true,
                //     position: true,
                //     rotation: true,
                //     uvs: true,
                //     alpha: true
                // })
                length: 0,
                con: new PIXI.mesh.Mesh(PIXI.Texture.fromImage("./images/snake_body.jpg"), new Float32Array([]), new Float32Array([]), new Uint16Array([])),
                chain: new PIXI.Graphics()
            }; //PIXI.mesh.Rope = new PIXI.mesh.Rope(PIXI.Texture.fromImage("/images/snake.jpg"), [])
            this._ANI = new Tween_1.default();
            /**身体蠕动曲线信息 */
            this._line = {
                length: 0
            };
            this.is_ignore = false;
            this.is_stop = false;
            this.is_sprint = false;
            /**尾部延迟增长 */
            this._delay_num = 0;
            /**方向延迟增长 */
            this._delay_deg = 0;
            /**方向旋转的时候是否顺时针 */
            this._is_clockwise = true;
            this._light = new PIXI.lights.PointLight(0xffffff, 2);
            this._c_r = ~~(Math.random() * 256);
            this._c_g = ~~(Math.random() * 256);
            this._c_b = ~~(Math.random() * 256);
            this._c_a = Math.min(Math.max(Math.random() + 0.3, 0.3), 1);
            this._c_thit = 65536 /*256 * 256*/ * this._c_r + 256 * this._c_g + this._c_b;
            this._knotGra = (function () {
                var knotGra = new PIXI.Graphics();
                knotGra.beginFill(0xffffff);
                knotGra.drawCircle(0, 0, MaxKnotTexWidth);
                knotGra.endFill();
                return knotGra;
            })();
            this._knotTexLen = 20;
            this._knotTexList = (function () {
                var _knotGra = _this._knotGra;
                /**节点周期为20 */
                var len = _this._knotTexLen;
                var _thit = _this._c_thit;
                var res = [];
                for (var i = 0; i < 20; i += 1) {
                    var color_proportion = Math.abs((i % 20) / 20 - 0.5) + 0.5; //[0.5~0~0.5]
                    _knotGra.tint = _thit * color_proportion;
                    res.push(_knotGra.generateTexture(common_1.renderer));
                }
                return res;
            })();
            this._delay_num = snake_shape.body.length;
            this.addChild(this._body.con);
            this.importShape(snake_shape);
            // var snake_body_tex = PIXI.Texture.fromImage("./images/snake_body.png");
            // if (snake_body_tex.hasLoaded) {
            // }
            this.addChild(this._body.chain);
            this._body.chain.alpha = 0.5;
            // this._body.chain.scale.set(2,2);
            // this.addChild(this._light);
            this._ani_move();
        }
        Snake.prototype.updateRopePoints = function () {
            var _cur_points = this._body.points;
            var points = _cur_points;
            var rope = this._body.con;
            var texture = rope.texture;
            var base_spacing = this._base_spacing;
            if (texture.height) {
                var skinData = this._skin.body_colors;
                // if (!texture["is_scaled"]) {
                //     texture["is_scaled"] = true;
                var source_tex_height = texture.height;
                var density = this._density;
                var target_tex_height = density * 2;
                texture.height = target_tex_height;
                texture.width = texture.width * target_tex_height / source_tex_height;
                this._resizeHead();
                // }
                /** */
                // try {
                var _pre_points = this._pre_points;
                if (_pre_points && this._is_use_pre_points) {
                    var _pre_points_fps_i = this._pre_points_fps_i += 1;
                    var _pre_points_fps = this._pre_points_fps;
                    this._pre_points = points = common_1.LineAnimate(_pre_points, _cur_points, _pre_points_fps_i / _pre_points_fps);
                    if (_pre_points_fps_i >= _pre_points_fps) {
                        this._is_use_pre_points = false;
                    }
                }
                else {
                    this._pre_points = points = this._pre_points ? common_1.LineAnimate(this._pre_points, _cur_points, 0.5) : _cur_points;
                }
                // } catch (e) {
                //     debugger
                // }
                var pathNode = this._path;
                pathNode.setAttribute("d", points.map(function (point, i) {
                    // if (isNaN(point.x * point.y)) {
                    //     debugger
                    // }
                    if (i === 0) {
                        return "M " + point.x + " " + point.y + "C " + point.x + " " + point.y;
                    }
                    else if (i < points.length - 1) {
                        var pre_point = points[i - 1];
                        var nex_point = points[i + 1];
                        var a = common_1.getAnchors(pre_point.x, pre_point.y, point.x, point.y, nex_point.x, nex_point.y);
                        if (isNaN(a.x1)) {
                            return "";
                        }
                        return a.x1 + " " + a.y1 + " " + point.x + " " + point.y + " " + a.x2 + " " + a.y2;
                    }
                    else {
                        return point.x + " " + point.y + " " + point.x + " " + point.y;
                    }
                }).join(" "));
                var tex_width = texture.width;
                var snake_body_length = this._body.length; //points.length * base_spacing;
                var point_childrens = rope.children;
                var res_points = [];
                for (var total_path_length = pathNode.getTotalLength(), l = total_path_length, unit_l = base_spacing / 1.2 * total_path_length / snake_body_length, i = 0, total_i = Math.ceil(total_path_length / unit_l); l > 0 || ((l = 0) || true); l -= unit_l, i += 1) {
                    var cur_point = pathNode.getPointAtLength(l);
                    res_points.push(cur_point);
                    var inv_i = total_i - i;
                    var inv_index = point_childrens.length - 1 - i;
                    if (inv_index < 0) {
                        var point_sprite = new PIXI.Sprite(PIXI.Texture.fromImage("/images/snake_body_unit_v3.png"));
                        point_sprite.anchor.set(0.5, 0.5);
                        point_sprite.tint = skinData[i % skinData.length];
                        rope.addChildAt(point_sprite, 0);
                    }
                    else {
                        var point_sprite = point_childrens[inv_index];
                    }
                    point_sprite.width = target_tex_height;
                    point_sprite.height = target_tex_height;
                    point_sprite.position.set(cur_point.x, cur_point.y);
                    if (this.is_sprint) {
                        point_sprite.blendMode = PIXI.BLEND_MODES.ADD;
                    }
                    else {
                        point_sprite.blendMode = PIXI.BLEND_MODES.NORMAL;
                    }
                    if (l <= 0) {
                        for (var c_len = point_childrens.length, i = i + 1; i < c_len; c_len -= 1) {
                            rope.removeChildAt(0);
                        }
                        break;
                    }
                }
                // for (var i = 0; i < points.length; i += 1) {
                //     var cur_point = points[i];
                //     res_points.push(cur_point)
                //     var point_sprite = <PIXI.Sprite>point_childrens[i];
                //     if (!point_sprite) {
                //         point_sprite = new PIXI.Sprite(PIXI.Texture.fromImage("/images/snake_body_unit_v3.png"))
                //         point_sprite.anchor.set(0.5, 0.5)
                //         point_sprite.tint = skinData[i % skinData.length];
                //         rope.addChild(point_sprite);
                //     }
                //     point_sprite.width = target_tex_height;
                //     point_sprite.height = target_tex_height;
                //     point_sprite.position.set(cur_point.x, cur_point.y);
                // }
                // for (var c_len = point_childrens.length, i = i + 1; i < c_len; c_len -= 1) {
                //     rope.removeChildAt(i);
                // }
                var renderPoints = function (g) {
                    var childs = g.children;
                    if (!childs.length) {
                        var g1_line = new PIXI.Graphics();
                        var g1_point = new PIXI.Graphics();
                        g.addChild(g1_line);
                        g.addChild(g1_point);
                        var g2_line = new PIXI.Graphics();
                        var g2_point = new PIXI.Graphics();
                        g.addChild(g2_line);
                        g.addChild(g2_point);
                        var g3_path = new PIXI.Graphics();
                        g3_path["svg_help"] = new SVGGraphics_1.default(g3_path);
                        g.addChild(g3_path);
                    }
                    else {
                        var g1_line = childs[0];
                        var g1_point = childs[1];
                        var g2_line = childs[2];
                        var g2_point = childs[3];
                        var g3_path = childs[4];
                        g1_line.clear();
                        g1_point.clear();
                        g2_line.clear();
                        g2_point.clear();
                        g3_path.clear();
                    }
                    g1_line.lineStyle(.5, 0xffc2c2);
                    g1_point.lineStyle(.5, 0xffc2c2);
                    g1_line.moveTo(points[0].x, points[0].y);
                    for (var i = 0; i < points.length; i++) {
                        if (i > 0) {
                            g1_line.lineTo(points[i].x, points[i].y);
                        }
                        g1_point.beginFill(0xff0022);
                        g1_point.drawCircle(points[i].x, points[i].y, 2);
                        g1_point.endFill();
                    }
                    ;
                    // g2_line.lineStyle(.5, 0xc2c2ff);
                    // g2_point.lineStyle(.5, 0xc2c2ff);
                    // g2_line.moveTo(res_points[0].x, res_points[0].y);
                    // for (var i = 0; i < res_points.length; i++) {
                    //     if (i > 0) {
                    //         g2_line.lineTo(res_points[i].x, res_points[i].y);
                    //     }
                    //     g2_point.beginFill(0x0022ff);
                    //     g2_point.drawCircle(res_points[i].x, res_points[i].y, 2);
                    //     g2_point.endFill();
                    // };
                    // var svg_help = <SVGGraphics>g3_path["svg_help"];
                    // svg_help.drawNode(pathNode);
                };
            }
        };
        Snake.prototype.waitingForImportData = function () {
            this._ANI.Tween("turnMySnakeHeadWithSlowDown", this)
                .to({
                _speed: this._speed / 10
            }, common_1.S_ANI_TIME)
                .start();
            this._is_WFID = true;
        };
        Snake.prototype._ani_move = function () {
            var _pre_time = Date.now();
            var snake = this;
            // requestAnimationFrame(function _ani() {
            //     var _cur_time = Date.now();
            //     snake.update(_cur_time - _pre_time);
            //     _pre_time = _cur_time;
            //     requestAnimationFrame(_ani);
            // });
            requestAnimationFrame(function _ani() {
                requestAnimationFrame(_ani);
                var _cur_time = Date.now();
                var _dif_time = _cur_time - _pre_time;
                snake.update(_dif_time);
                snake.updateDirection(_dif_time);
                _pre_time = _cur_time;
            });
        };
        Snake.prototype.update = function (delay_time) {
            if (this.is_stop) {
                return;
            }
            var base_spacing = this._base_spacing;
            // 这条蛇进行一次偏移所需要的时间
            var unit_time = base_speed / this._speed * 100;
            // 这次运动计算的偏移比例
            var p = delay_time / unit_time;
            var points = this._body.points;
            var source_distance = base_speed * p;
            var current_delay_num = this._delay_num;
            var distance = source_distance;
            if (current_delay_num < 0) {
                if (-current_delay_num >= source_distance) {
                    var distance = 0;
                    current_delay_num += source_distance;
                }
                else {
                    var distance = source_distance + current_delay_num;
                    current_delay_num = 0;
                }
            }
            if (distance) {
                for (var len = points.length, cur_index = len - 2, nex_index = cur_index + 1; distance > 0; cur_index += 1, nex_index = cur_index + 1) {
                    var nex_point = points[nex_index];
                    var cur_point = points[cur_index];
                    var point_dis = 0;
                    if (nex_point) {
                        point_dis = Math.sqrt(Math.pow(nex_point.x - cur_point.x, 2) + Math.pow(nex_point.y - cur_point.y, 2));
                    }
                    /**
                     * 距离为空有两种情况，
                     * 一种是：最后两个顶点之间没有距离，就无法确定xy_rate
                     * 一种是：nex_index > points.length - 1，属于超过最后一个顶点的新店
                     */
                    if (!point_dis) {
                        var xy_rate = Math.tan((this._direction / 180) * Math.PI);
                        var symbol_x = this._direction < 180 ? 1 : -1;
                        var symbol_y = this._direction > 90 && this._direction < 270 ? -1 : 1;
                    }
                    else {
                        var xy_rate = (nex_point.x - cur_point.x) / (nex_point.y - cur_point.y);
                        var symbol_x = nex_point.x > cur_point.x ? 1 : -1;
                        var symbol_y = nex_point.y > cur_point.y ? 1 : -1;
                    }
                    if (!nex_point) {
                        nex_point = popCGPoint();
                        points.push(nex_point);
                        var move_dis = Math.min(distance, base_spacing);
                        distance -= move_dis;
                    }
                    else if (point_dis >= base_spacing) {
                        continue;
                    }
                    else {
                        var move_dis = Math.min(distance + point_dis, //如果增长空间足够用
                        base_spacing);
                        distance -= move_dis - point_dis;
                    }
                    var xy_rate_pow_2 = xy_rate * xy_rate;
                    var add_x = symbol_x * move_dis / Math.sqrt(1 + 1 / xy_rate_pow_2);
                    var add_y = symbol_y * move_dis / Math.sqrt(1 + xy_rate_pow_2);
                    var nex_x = cur_point.x + add_x;
                    var nex_y = cur_point.y + add_y;
                    if (nex_x === cur_point.x && nex_y === cur_point.y) {
                        points.pop();
                    }
                    else {
                        nex_point.x = nex_x;
                        nex_point.y = nex_y;
                    }
                }
            }
            var distance = source_distance;
            if (current_delay_num > 0) {
                if (current_delay_num >= source_distance) {
                    var distance = 0;
                    current_delay_num -= source_distance;
                }
                else {
                    var distance = source_distance - current_delay_num;
                    current_delay_num = 0;
                }
            }
            if (distance) {
                for (var cur_index = 1, pre_index = 0, len = points.length; distance > 0; cur_index += 1, pre_index = cur_index - 1) {
                    var pre_point = points[pre_index];
                    var cur_point = points[cur_index];
                    var point_dis = Math.sqrt(Math.pow(cur_point.x - pre_point.x, 2) + Math.pow(cur_point.y - pre_point.y, 2));
                    var move_dis = Math.min(distance, base_spacing); //所要缩短的距离
                    if (move_dis >= point_dis) {
                        distance -= point_dis;
                        CG_points.push(pre_point);
                        points.splice(pre_index, 1);
                        cur_index -= 1;
                    }
                    else {
                        distance -= move_dis;
                        var xy_rate_pow_2 = Math.pow((cur_point.x - pre_point.x) / (cur_point.y - pre_point.y), 2);
                        var symbol_x = pre_point.x > cur_point.x ? 1 : -1;
                        var symbol_y = pre_point.y > cur_point.y ? 1 : -1;
                        var cut_x = symbol_x * (point_dis - move_dis) / Math.sqrt(1 + 1 / xy_rate_pow_2);
                        var cut_y = symbol_y * (point_dis - move_dis) / Math.sqrt(1 + xy_rate_pow_2);
                        // console.log("cut_x:", [cur_point.x, pre_point.x, cut_x], "cut_y:", [cur_point.y, pre_point.y, cut_y]);
                        pre_point.x = cur_point.x + cut_x;
                        pre_point.y = cur_point.y + cut_y;
                        break;
                    }
                }
            }
            var body_length = this._body.length += this._delay_num - current_delay_num;
            this._delay_num = current_delay_num;
            this._density = common_1.cbrt(body_length * 2) + 12;
            this._base_spacing = common_1.cbrt(body_length * 2);
            var snake_head = this._head;
            if (snake_head) {
                var head_point = points[points.length - 1];
                snake_head.x = head_point.x;
                snake_head.y = head_point.y;
                this._light.position.set(head_point.x, head_point.y);
            }
            this.updateRopePoints();
        };
        Snake.prototype.importShape = function (snake_shape) {
            var skin = this._skin = (snake_shape.skin && skinMap[snake_shape.skin]) || skinMap[skinNames[Math.floor(Math.random() * skinNames.length)]];
            this._setHead(skin.head_url, skin.head_effective_width, skin.head_anchor);
            this._setTail(snake_shape.tail);
            var offset = snake_shape.body.offset;
            this.x = offset.x;
            this.y = offset.y;
            var points = snake_shape.body.points.map(function (point) {
                return new PIXI.Point(point.x, point.y);
            });
            // updateRopePoints(this._body, points);
            this._body.points = points;
            this._density = snake_shape.density || common_1.cbrt(snake_shape.body.length * 2) + 12;
            this._speed = snake_shape.speed;
            this._sensitivity = snake_shape.sensitivity;
            this._direction = snake_shape.direction;
            this.updateRopePoints();
        };
        Snake.prototype.importData = function (snake_data) {
            if (this._is_WFID) {
                this._is_WFID = false;
                this._ANI.Tween("turnMySnakeHeadWithSlowDown").stop();
                //开启平滑帧
                this._is_use_pre_points = true;
                this._pre_points_fps = 10;
                this._pre_points_fps_i = 0;
            }
            var body_points = this._body.points;
            for (var i = 0, point_info; point_info = snake_data.points[i]; i += 1) {
                var current_point = body_points[i];
                if (!current_point) {
                    current_point = body_points[i] = popCGPoint();
                }
                current_point.copy(point_info);
            }
            if (i < body_points.length) {
                CG_points.push.apply(CG_points, body_points.splice(i, body_points.length - i + 1));
            }
            this._body.length = snake_data.body_length;
            this._id = snake_data.id;
            this._density = snake_data.density || common_1.cbrt(snake_data.body_length * 2) + 12;
            this._speed = snake_data.speed;
            this._sensitivity = snake_data.sensitivity;
            this._direction = snake_data.direction;
            this._delay_num = snake_data.delay_num;
            //将要增长的长度
            if (snake_data.delay_num === undefined) {
                var current_body_length = this.getBodyLength();
                this._delay_num = this._body.length - current_body_length;
                this._body.length = current_body_length;
            }
            else {
                this._delay_num = snake_data.delay_num;
            }
            this._delay_deg = snake_data.delay_deg;
            this._is_clockwise = !!snake_data.is_clockwise;
            this.is_ignore = !!snake_data.is_ignore;
            this.is_stop = !!snake_data.is_stop;
            this.is_sprint = snake_data.is_sprint;
            this.updateRopePoints();
        };
        Snake.prototype.getBodyLength = function () {
            var points = this._body.points;
            var pre_point;
            var total_body_length = 0;
            for (var _i = 0, points_2 = points; _i < points_2.length; _i++) {
                var cur_point = points_2[_i];
                if (!cur_point) {
                    break;
                }
                if (!pre_point) {
                    pre_point = cur_point;
                    continue;
                }
                total_body_length += Math.sqrt(Math.pow(cur_point.x - pre_point.x, 2) + Math.pow(cur_point.y - pre_point.y, 2));
                pre_point = cur_point;
            }
            return total_body_length;
        };
        Snake.prototype._setHead = function (head_url, effective_width, anchor) {
            var _this = this;
            if (anchor === void 0) { anchor = { x: 0.5, y: 0.5 }; }
            if (this._head) {
                this.removeChild(this._head);
                this._head = null;
            }
            if (head_url) {
                var tex = PIXI.Texture.fromImage(head_url);
                var head = this._head = new PIXI.Sprite(tex);
                head.anchor.copy(anchor);
                this.addChild(head);
                tex.once("update", function () {
                    _this._effective_width = effective_width || tex.width;
                    _this._resizeHead();
                });
            }
        };
        Snake.prototype._resizeHead = function () {
            if (this._head) {
                var effective_width = this._effective_width;
                var scale = this._head.scale;
                scale.x = scale.y = this._density * 2 / effective_width;
            }
        };
        Snake.prototype._setTail = function (tail_url) {
            if (this._tail) {
                this.removeChild(this._tail);
                this._tail = null;
            }
            if (tail_url) {
                this._tail = PIXI.Sprite.fromImage(tail_url);
                this.addChild(this._tail);
            }
        };
        Snake.prototype.exportShape = function () {
            var _offset = this.getBounds();
            return {
                head: this._head._texture.imageUrl,
                body: {
                    offset: {
                        x: _offset.x,
                        y: _offset.y
                    },
                    length: this._body.length,
                    points: this._body.points.map(function (point) { return { x: point.x, y: point.y }; })
                },
                density: this._density,
                speed: this._speed,
                sensitivity: this._sensitivity,
                direction: this._direction
            };
        };
        Snake.prototype._addBodyColorPoint = function (i) {
            var knot = new PIXI.Sprite(this._knotTexList[i % this._knotTexLen]);
            knot.width = knot.height = this._density * 2;
            knot.anchor.set(.5, .5);
            knot.alpha = this._c_a;
            this._body.con.addChild(knot);
            return knot;
        };
        /**身体成长 */
        Snake.prototype.addBody = function (num) {
            this._delay_num += num;
        };
        Snake.prototype.addSpeed = function (num) {
            this._speed += num;
            // this._ani_move();
        };
        Snake.prototype.addSensitivity = function (num) {
            this._sensitivity += num;
        };
        Snake.prototype.turnHead = function (deg) {
            var _direction = this._direction;
            var dif_deg = Math.abs(deg - _direction);
            if (!dif_deg) {
                return;
            }
            var _is_clockwise = false;
            // 顺时针的角度范围
            var _left_deg_range = _direction - 180;
            if (_direction < 180) {
                if (deg < _direction || deg > _left_deg_range + 360) {
                    _is_clockwise = true;
                }
            }
            else {
                if (deg > _left_deg_range && deg < _direction) {
                    _is_clockwise = true;
                }
            }
            if (dif_deg > 180) {
                this._delay_deg = 360 - dif_deg;
            }
            else {
                this._delay_deg = dif_deg;
            }
            this._is_clockwise = _is_clockwise;
        };
        Snake.prototype.updateDirection = function (delay_time) {
            if (this.is_stop) {
                return;
            }
            var _delay_deg = this._delay_deg;
            if (!_delay_deg) {
                return;
            }
            // 这条蛇进行一次转向所需要的时间
            var unit_time = 360 / this._sensitivity * 100;
            // 这次运动计算的旋转角度
            var deg = delay_time / unit_time * base_deg;
            if (deg < _delay_deg) {
                this._delay_deg -= deg;
                var move_deg = deg;
            }
            else {
                this._delay_deg = 0;
                move_deg = _delay_deg;
            }
            var _direction = this._direction;
            if (this._is_clockwise) {
                _direction -= move_deg;
                if (_direction < 0) {
                    _direction += 360;
                }
            }
            else {
                _direction += move_deg;
                if (_direction >= 360) {
                    _direction -= 360;
                }
            }
            this._direction = _direction;
            var snake_head = this._head;
            if (snake_head) {
                var res_rotation = ((_direction > 180) ? (540 - _direction) : Math.abs(_direction - 180)) / 180 * Math.PI;
                snake_head.rotation = res_rotation;
            }
        };
        Snake.prototype.run = function (time) {
            this._ANI.update(time);
            this._eatFoods();
            this._hitSnakes();
        };
        Snake.prototype.getPoint = function (point_index) {
            return this._body.points[point_index];
        };
        /**获取尾部对应的点 */
        Snake.prototype.getTailPoint = function () {
            return this._body.points[0];
        };
        /**获取头部对应的点 */
        Snake.prototype.getHeadPoint = function () {
            return this._body.points[this._body.points.length - 1];
        };
        /**投食：将可食用食物投入视野 */
        Snake.prototype.viewFoods = function (foods) {
            this._foods = foods;
        };
        Snake.prototype._eatFoods = function () {
            var self = this;
            var foods = self._foods;
            if (foods) {
                var head = self.getHeadPoint();
                var density = self._density;
                var mouth = common_1.movePointWithDirection(self._direction, density, head);
                // self._head.position.set(mouth.x,mouth.y)
                var r_pow_2_1 = Math.pow(density + density, 2);
                var eated_food = foods.getCollisionItemWithCircle(mouth.x, mouth.y, density, function (food, x, y) {
                    return (Math.pow(x - food.x, 2) + Math.pow(y - food.y, 2)) <= r_pow_2_1;
                });
                var eated_points = [];
                eated_food.children_indexs.length && eated_food.children_indexs.forEach(function (remover_index, i) {
                    var food = foods.getChildAt(remover_index);
                    eated_points.push(food);
                    food.onEat(self);
                });
                eated_food.emiter_pos_indexs.length && eated_food.emiter_pos_indexs.forEach(function (remover_index, i) {
                    var eat_able_food = foods.removeParticleFoodAt(remover_index - i, {
                        get fly_to() {
                            return common_1.movePointWithDirection(self._direction, self._density, self.getHeadPoint());
                        }
                    });
                    eated_points.push(eat_able_food);
                    Food_1.default.prototype.effectFood.call(eat_able_food, self);
                });
                if (eated_points.length) {
                    self.emit("eated_food", eated_points);
                }
                foods.update();
            }
        };
        /**竞争：将其它对手投入视野 */
        Snake.prototype.viewSnake = function (snakes) {
            this._snakes = snakes;
        };
        Snake.prototype._hitSnakes = function () {
            var snakes = this._snakes;
            if (snakes) {
                var head = this.getHeadPoint();
                var density_1 = this._density;
                var hit_snake = snakes.getCollisionItem(head.x, head.y, function (snake, point_index, x, y) {
                    var point = snake.getPoint(point_index);
                    return !snake.is_ignore && (Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2)) <= Math.pow(density_1 + snake._density, 2);
                });
                // this._foods && hit_snake.forEach(snake => {
                //     snake.is_ignore = true;
                //     snake.is_stop = true;
                //     snake._ANI.Tween(snake)
                //         .to({
                //             alpha: 0
                //         }, 1025)
                //         .onComplete(() => {
                //             snakes.removeChild(snake)
                //         })
                //         .start();
                //     snake.die(this._foods)
                // })
                if (hit_snake.length) {
                    this.emit("died", hit_snake);
                }
            }
        };
        // die(food_con: FoodContainer) {
        //     var points = this._body.points;
        //     var density = this._density;
        //     var total_body = points.length;
        //     var total_speed = this._speed;
        //     // var total_sensitivity = this._sensitivity;
        //     var unit_body = 1;
        //     var unit_speed = total_speed / total_speed;
        //     var unit_sensitivity = 2;//total_sensitivity / total_speed;
        //     var rem_body = total_body;
        //     var rem_speed = unit_speed * total_body;
        //     var rem_sensitivity = unit_sensitivity * total_body;
        //     var total_sensitivity = rem_sensitivity;
        //     points.forEach((point, i) => {
        //         var add_body = i * unit_body >= total_body - rem_body ? unit_body * Math.round(Math.random() * 2) : 0
        //         rem_body -= add_body;
        //         var add_speed = i * unit_speed >= total_speed - rem_speed ? unit_speed * Math.round(Math.random() * 2) : 0
        //         rem_speed -= add_speed;
        //         var add_sensitivity = i * unit_sensitivity >= total_sensitivity - rem_sensitivity ? unit_sensitivity * Math.round(Math.random() * 2) : 0
        //         rem_sensitivity -= add_sensitivity;
        //         food_con.addParticleFood(new FoodEffect({
        //             add_body: add_body,
        //             add_speed: add_speed,
        //             add_sensitivity: add_sensitivity,
        //         }), point.x + (Math.random() - 0.5) * 2 * density, point.y + (Math.random() - 0.5) * 2 * density)
        //     })
        // }
        Snake.prototype.die = function () {
            var _this = this;
            this.is_ignore = true;
            this.is_stop = true;
            this._ANI.Tween(this)
                .to({
                alpha: 0
            }, 1025)
                .onComplete(function () {
                _this.parent && _this.parent.removeChild(_this);
            })
                .start();
        };
        return Snake;
    }(PIXI.Container));
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.default = Snake;
    var SnakeContainer = (function (_super) {
        __extends(SnakeContainer, _super);
        function SnakeContainer() {
            _super.call(this);
        }
        SnakeContainer.prototype.addSnake = function (snake) {
            this.addChild(snake);
        };
        SnakeContainer.prototype.getCollisionItem = function (x, y, filter) {
            return this.children.filter(function (snake) {
                for (var i = 0, len = snake._body.points.length; i < len; i += 1) {
                    if (filter(snake, i, x, y)) {
                        return true;
                    }
                }
                return false;
            });
        };
        return SnakeContainer;
    }(PIXI.Container));
    exports.SnakeContainer = SnakeContainer;
});
